# -*- coding: utf-8 -*-
"""
权限管理控制器
提供用户权限管理、管理员操作、权限分配等功能
"""
from typing import List, Optional

from loguru import logger
from fastapi import Request
from pydantic import BaseModel

from schemas.response_entity import JsonModel
from db.repository.user import (
    db_get_user_by_id,
    db_update_user,
    db_create_user,
    db_check_user_exists,
    db_restore_user,
    db_check_user_in_group,
    db_add_user_to_group,
    db_get_user_permissions,
    db_get_user_group_ids
)
from db.repository.user_group import (
    db_get_group_by_id_for_permission,
    db_check_permission_exists,
    db_add_permission_to_group,
    db_remove_permission_from_group
)


# ==================== 数据模型定义 ====================

class AUserUPEntity(BaseModel):
    """管理员用户更新实体"""
    token: str
    user_id: int
    new_password: str = None
    nickname: str = None
    company: Optional[str] = None
    role: str = None


class AUserCEntity(BaseModel):
    """管理员创建用户实体"""
    token: str
    username: str
    nickname: str = None
    password: str
    company: str = None
    role: str = "normal"
    group_ids: List[int] = []


class APermissEntity(BaseModel):
    """权限管理实体"""
    token: str
    permission: str
    group_id: int


# ==================== 工具函数 ====================

def is_valid_phone(phone: str) -> bool:
    """验证是否为合法手机号(11位数字)"""
    import re
    pattern = r'^1[0-9]{10}$'  # 第一位为1，其余为0-9的10位数字
    return bool(re.match(pattern, phone))


# 权限管理
prefix_permissions = {
    "knowledge": 1,
    "image": 1,
    "clause": 1,
    "exam": 1,
}


# ==================== API接口函数 ====================

# 管理员更新用户
async def admin_update_user(request: Request, payload: AUserUPEntity):
    """
    管理员更新用户信息
    
    Args:
        request: FastAPI请求对象
        payload: 管理员用户更新数据
        
    Returns:
        JsonModel: 更新结果响应
    """
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg=f"用户token 非法").to_response()
    
    try:
        if payload.role is not None and payload.role not in ["normal", "admin", "superman"]:
            return JsonModel(code=400, data=None, msg=f"角色非法").to_response()
        
        if not user.check_admin_role():
            return JsonModel(code=403, data=None, msg="用户无权限").to_response()

        update_user = db_get_user_by_id(payload.user_id)
        if update_user is None:
            return JsonModel(code=404, data=None, msg=f"用户未找到").to_response()
        
        # 更新用户信息
        db_update_user(
            payload.user_id,
            nickname=payload.nickname,
            company=payload.company,
            password=payload.new_password,
            role=payload.role
        )

        return JsonModel(code=200, data=None, msg=f"用户更新成功").to_response()
    except Exception as e:
        logger.error(f"管理员更新用户失败: {str(e)}")
        return JsonModel(code=500, data=None, msg="服务器内部错误").to_response()


# 管理员创建用户
async def admin_add_user(request: Request, payload: AUserCEntity):
    """
    管理员创建用户
    
    Args:
        request: FastAPI请求对象
        payload: 管理员创建用户数据
        
    Returns:
        JsonModel: 创建结果响应
    """
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg=f"用户token 非法").to_response()
    
    try:
        if payload.role not in ["normal", "admin", "superman"]:
            return JsonModel(code=400, data=None, msg=f"角色非法").to_response()
        
        if not user.check_admin_role():
            return JsonModel(code=403, data=None, msg="用户无权限").to_response()
        
        if user.role == "admin" and payload.role == "superman":
            return JsonModel(code=403, data=None, msg=f"角色非法").to_response()
        
        if not is_valid_phone(payload.username):
            return JsonModel(code=400, data=None, msg="请输入正确的手机号").to_response()
        
        # 检查用户是否已存在
        existing_user = db_check_user_exists(payload.username)
        if existing_user and not existing_user.is_delete:
            return JsonModel(code=400, data=None, msg="用户已存在").to_response()
        
        if len(payload.password) < 6:
            return JsonModel(code=400, data=None, msg="密码小于6位").to_response()
        
        if payload.nickname is None:
            payload.nickname = payload.username
        
        # 创建或恢复用户
        if existing_user and existing_user.is_delete:
            db_user = db_restore_user(
                payload.username,
                payload.nickname,
                payload.password,
                payload.company,
                payload.role
            )
        else:
            db_user = db_create_user(
                payload.username,
                payload.nickname,
                payload.password,
                payload.company,
                payload.role
            )
        
        # 将用户添加到指定组
        for group_id in payload.group_ids:
            group = db_get_group_by_id_for_permission(group_id)
            if group is None:
                return JsonModel(code=404, data=None, msg=f"用户组:{group_id}未匹配到").to_response()
            
            if not db_check_user_in_group(db_user.id, group_id):
                db_add_user_to_group(db_user.id, group_id)

        return JsonModel(code=200, data=None, msg="用户创建成功").to_response()
    except Exception as e:
        logger.error(f"管理员创建用户失败: {str(e)}")
        return JsonModel(code=500, data=None, msg="服务器内部错误").to_response()


# 添加权限到组
async def add_permission_to_group(request: Request, payload: APermissEntity):
    """
    为组添加权限
    
    Args:
        request: FastAPI请求对象
        payload: 权限管理数据
        
    Returns:
        JsonModel: 操作结果响应
    """
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg=f"用户token 非法").to_response()
    
    try:
        if not prefix_permissions.get(payload.permission):
            return JsonModel(code=400, data=None, msg=f"权限非法").to_response()
        
        if not user.check_superman_role():
            return JsonModel(code=403, data=None, msg="用户无权限").to_response()

        # 检查组是否存在
        group = db_get_group_by_id_for_permission(payload.group_id)
        if not group:
            return JsonModel(code=404, data=None, msg="用户组不存在").to_response()
        
        # 检查权限是否已存在
        if db_check_permission_exists(payload.group_id, payload.permission):
            return JsonModel(code=400, data=None, msg="此权限已存在").to_response()
        
        # 添加权限
        db_add_permission_to_group(payload.group_id, payload.permission)

        return JsonModel(code=200, data=None, msg="权限添加成功").to_response()
    except Exception as e:
        logger.error(f"添加权限失败: {str(e)}")
        return JsonModel(code=500, data=None, msg="服务器内部错误").to_response()


# 从组中删除权限
async def remove_permission_from_group(request: Request, payload: APermissEntity):
    """
    从组中删除权限
    
    Args:
        request: FastAPI请求对象
        payload: 权限管理数据
        
    Returns:
        JsonModel: 操作结果响应
    """
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg=f"用户token 非法").to_response()
    
    try:
        if not prefix_permissions.get(payload.permission):
            return JsonModel(code=400, data=None, msg=f"权限非法").to_response()
        
        if not user.check_superman_role():
            return JsonModel(code=403, data=None, msg="用户无权限").to_response()

        # 检查组是否存在
        group = db_get_group_by_id_for_permission(payload.group_id)
        if not group:
            return JsonModel(code=404, data=None, msg="用户组不存在").to_response()
        
        # 检查权限是否存在
        if not db_check_permission_exists(payload.group_id, payload.permission):
            return JsonModel(code=404, data=None, msg="权限不存在").to_response()
        
        # 删除权限
        db_remove_permission_from_group(payload.group_id, payload.permission)

        return JsonModel(code=200, data=None, msg="权限移除成功").to_response()
    except Exception as e:
        logger.error(f"删除权限失败: {str(e)}")
        return JsonModel(code=500, data=None, msg="服务器内部错误").to_response()


# 获取用户权限列表
async def get_user_permissions(request: Request, token: str, user_id: int):
    """
    获取用户权限列表
    
    Args:
        request: FastAPI请求对象
        token: 用户认证token
        user_id: 目标用户ID
        
    Returns:
        JsonModel: 权限列表响应
    """
    user = request.state.user
    if user is None:
        return JsonModel(code=401, data=None, msg=f"用户token 非法").to_response()
    
    try:
        target_user = db_get_user_by_id(user_id)
        if target_user is None:
            return JsonModel(code=404, data=None, msg=f"用户未找到").to_response()
        
        permissions = []
        
        if user.check_superman_role():
            if target_user.check_superman_role():
                permissions = list(prefix_permissions.keys())
            else:
                permissions = db_get_user_permissions(user_id)
        elif user.check_admin_role():
            if target_user.check_superman_role():
                permissions = list(prefix_permissions.keys())
            else:
                user_groups = db_get_user_group_ids(user)
                permissions = db_get_user_permissions(user_id, user_groups)
        elif user.id == target_user.id:
            permissions = db_get_user_permissions(user_id)
        
        return JsonModel(code=200, data=permissions, msg="success").to_response()
    except Exception as e:
        logger.error(f"获取用户权限失败: {str(e)}")
        return JsonModel(code=500, data=None, msg="服务器内部错误").to_response()
